home *** CD-ROM | disk | FTP | other *** search
- /*
- * Program: None
- * Module: MxMatrix.c
- * Programmer: John Buchanan
- *
- * Description:
- * A variety of routines to handle matrices.
- *
- */
-
- /* Exported functions */
- #define MX_N 4
- #include "MxMatrix.h"
- #include <math.h>
- #include <stdio.h>
- typedef float matrix[MX_N][MX_N];
- typedef float vector[MX_N];
- #define DAMN_SMALL 1.0e-10
-
-
- void MxCopy(a,b) /* Copy a to b */
- matrix a,b;
- {
- register int i,j;
- for(i = 0; i < MX_N; i++)
- for(j = 0; j < MX_N; j++)
- b[i][j]=a[i][j];
- }
- void MxTranspose(a,r) /* Transpose a into result r */
- matrix a,r;
- {
- register int i,j;
- matrix tmp;
- for(i = 0; i < MX_N; i++)
- for(j = 0; j < MX_N; j++)
- tmp[j][i]=a[i][j];
- MxCopy(tmp,r);
- }
-
-
- void MxTranslate(a,x,y,z)
- matrix a;
- float x,y,z;
- {
- a[3][0] = x;
- a[3][1] = y;
- a[3][2] = z;
- }
-
- void MxScale(a,x,y,z)
- matrix a;
- float x,y,z;
- {
- a[0][0] = x;
- a[1][1] = y;
- a[2][2] = z;
- }
-
- void MxRotateD(a,degrees,axis) /* Create rotation matrix result r */
- matrix a;
- float degrees;
- char axis;
- {
- MxRotateR(a,degrees/180.0*M_PI,axis);
- }
-
- void MxRotateR(a,radians,axis) /* Create rotation matrix result r */
- matrix a;
- float radians;
- char axis;
- {
- float Cos,Sin;
- Cos = cos(radians);
- Sin = sin(radians);
- switch(axis)
- {
- case 'x':
- case 'X':
- a[1][1] = Cos;
- a[1][2] = Sin;
- a[2][1] = -Sin;
- a[2][2] = Cos;
- break;
- case 'y':
- case 'Y':
- a[0][0] = Cos;
- a[0][2] = -Sin;
- a[2][0] = Sin;
- a[2][2] = Cos;
- break;
- case 'z':
- case 'Z':
- a[0][0] = Cos;
- a[0][1] = Sin;
- a[1][0] = -Sin;
- a[1][1] = Cos;
- break;
- default:
- break;
- }
- }
-
-
- void MxIdentity(a) /* store the identity in a */
- matrix a;
- {
- register int i,j;
- for(i = 0; i < MX_N; i++)
- for(j = 0; j < MX_N; j++)
- a[i][j] = (i == j ? 1.0 : 0.0);
- }
- void MxScalarMultiply(s,a,r) /* multiply a by scalar s, put result in r */
- float s;
- matrix a,r;
- {
- register int i,j;
- for(i = 0; i < MX_N; i++)
- for(j = 0; j < MX_N; j++)
- r[i][j] = s * a[i][j];
- }
- void MxVectorMultiply(p,a,q) /* Multiply vector p by a into q */
- matrix a;
- vector p,q;
- {
- register int i,j;
- vector qTemp;
- for(i = 0; i < MX_N; i++)
- {
- qTemp[i] = 0.0;
- for(j = 0; j < MX_N; j++)
- qTemp[i] += p[j] * a[j][i];
- }
- VecCopy(qTemp,q);
- }
- void MxNegate(a,r) /* Negate a into r */
- matrix a,r;
- {
- register int i,j;
- for(i = 0; i < MX_N; i++)
- for(j = 0; j < MX_N; j++)
- r[i][j] = - a[i][j];
- }
- void MxAdd(a,b,r) /* add a and b into r */
- matrix a,b,r;
- {
- register int i,j;
- for(i = 0; i < MX_N; i++)
- for(j = 0; j < MX_N; j++)
- r[i][j] = a[i][j] + b[i][j];
- }
-
- void MxSubstract(a,b,r) /* substract b from a into r */
- matrix a,b,r;
- {
- register int i,j;
- for(i = 0; i < MX_N; i++)
- for(j = 0; j < MX_N; j++)
- r[i][j] = a[i][j] - b[i][j];
- }
-
- void MxMultiply(a,b,r) /* Multiply a by b put result in r */
- matrix a,b,r;
- {
- matrix tmp;
- register int i,j,k;
- for(i = 0; i < MX_N; i++)
- for(j = 0; j < MX_N; j++)
- {
- tmp[i][j] = 0.0;
- for(k = 0; k < MX_N; k++)
- tmp[i][j] += a[i][k] * b[k][j];
- }
- MxCopy(tmp,r);
- }
- void MxDivide(a,b,r)
- matrix a,b,r;
- {
- }
- void MxReverseDivide(a,b,r)
- matrix a,b,r;
- {
- }
-
- static char *MxOverFlow = "Mx Error: Stack overflow";
- static char *MxUnderFlow = "Mx Error: Stack underflow";
- static matrix MxStack[MX_STKLEN];
- static int MxStackTop = -1;
-
- int MxStackInit() /* initialize the stack */
- {
- MxStackTop = -1;
- }
- char *MxPush(m) /* Push matrix m onto stack */
- matrix m;
- {
- if(MxStackTop++ == MX_STKLEN)
- {
- MxStackTop--;
- return (MxOverFlow);
- }
- MxCopy(m,MxStack[MxStackTop]);
- return (NULL);
- }
- char *MxPop(m) /* place the matrix at the top of the stack in m */
- matrix m;
- {
- if(MxStackTop < 0)
- return(MxUnderFlow);
- MxCopy(MxStack[MxStackTop--],m);
- return (NULL);
- }
- float MxTranxform(a,b,m)
- vector a,b;
- matrix m;
- {
- }
- void MxPrint(m)
- matrix m;
- {
- register int i,j;
- printf("matrix output\n");
- for(i = 0; i < MX_N; i++)
- {
- for(j = 0; j < MX_N; j++)
- printf("\t%g",m[i][j]);
- printf("\n");
- }
- }
- void MxGet(m)
- matrix m;
- {
- register int i,j;
- printf("Enter the matrix at the prompts\n");
- for(i = 0; i < MX_N; i++)
- for(j = 0; j < MX_N; j++)
- {
- printf("m[%d][%d]:> ",i,j);
- scanf("%lf",&m[i][j]);
- }
- }
-
-
- void VecCopy(a,b)
- vector a,b;
- {
- register int i;
- for(i=0;i<MX_N;i++)
- b[i] = a[i];
- }
-
- void VecSubstract(a,b,c)
- vector a,b,c;
- {
- register int i;
- for(i=0;i<MX_N;i++)
- c[i] = a[i] - b[i];
-
- }
-
-
- void VecAdd(a,b,c)
- vector a,b,c;
- {
- register int i;
- for(i=0;i<MX_N;i++)
- c[i] = a[i] + b[i];
- }
-
- void VecCross(a,b,c)
- vector a,b,c;
- {
- register int i;
- vector tmp;
- tmp[0] = a[1]*b[2] - a[2]*b[1];
- tmp[1] = -(a[0]*b[2] - a[2]*b[0]);
- tmp[2] = a[0]*b[1] - a[1]*b[0];
- tmp[3] = 0.0; /* for now */
- VecCopy(tmp,c);
- }
- void VecPrint(a)
- vector a;
- {
- register int i;
- printf("vector output");
- for(i=0; i< MX_N; i++)
- printf("\t%g",a[i]);
- printf("\n");
- }
-
- float VecDot(p,q) /* Return dot product of p and q */
- vector p,q;
- {
- register int i;
- float result = 0.0;
- for (i=0; i< MX_N; i++)
- result += p[i] * q[i];
- return (result);
- }
-
- void VecNormalize(p)
- vector p;
- {
- register int i;
- float length = 0.0;
- for(i= 0; i< MX_N; i++)
- length += p[i]*p[i];
- if (length == 0.0)
- {
- fprintf(stderr,"zero length vector cannot be normalized\n");
- return;
- }
- length = sqrt(length);
- for(i= 0; i< MX_N; i++)
- p[i] = p[i] / length;
- }
- float VecLength(p)
- vector p;
- {
- register int i;
- float length = 0.0;
- for(i= 0; i< MX_N; i++)
- length += p[i]*p[i];
- return(sqrt(length));
- }
-
- VecScalarMultiply(a,v,d)
- float a;
- vector v;
- vector d;
- {
- register int i;
- for (i = 0; i< MX_N; i++)
- d[i] = v[i] *a;
- }
-
-
- static float MxElementMinor(a, i, j,order)
- register matrix a;
- register int i, j, order;
- {
- int k, l, ii, jj;
- float sign, MxDeterminant();
- register matrix new;
- sign = (((i+j) % 2 ) == 0 ) ? 1.0 : -1.0;
- /* copy matrix into smaller */
- k = 0;
- for (ii=0; ii<order; ii++) {
- if ( ii==i) continue;
- l=0;
- for (jj=0; jj<order; jj++) {
- if (jj==j) continue;
- new[k][l] = a[ii][jj];
- l++;
- };
- k++;
- };
- return(sign*MxDeterminant(new, MX_N-1));
- }
-
- float MxInvert(a,b)
- matrix a,b;
- {
- float det;
- float MxElementMinor(), MxDeterminant();
- register matrix at;
- int i, j;
- det = MxDeterminant(a, MX_N);
- if(det < DAMN_SMALL && det > -DAMN_SMALL)
- return(det);
- MxTranspose(a, at);
- for (i=0; i< MX_N; i++)
- for(j=0; j<MX_N; j++)
- b[i][j] = MxElementMinor(at, i, j, MX_N) / det;
- return(det);
- }
-
- float MxDeterminant ( a, order)
- register matrix a;
- int order;
- {
- float det, mux;
- register matrix new;
- int i, j, ii, jj, k, l;
-
- if( order ==1) return(a[0][0]);
- det = 0.0;
- mux = 1.0;
- i = 0;
- for (j=0; j<order; j++) {
- /* copy matrix into smaller */
- k = 0;
- for (ii=0; ii<order; ii++) {
- l=0;
- if (ii==i) continue;
- for (jj=0; jj<order; jj++) {
- if (jj==j) continue;
- new[k][l] = a[ii][jj];
- l++;
- };
- k++;
- };
- det += mux*a[i][j]*MxDeterminant(new, order-1);
- mux = -mux;
- };
- return(det);
- }
-
-
-